package vsvm.gui.forms;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import vsvm.classifier.AbstractClassifier;
import vsvm.classifier.AbstractTestSet;
import vsvm.classifier.TestingParameters;
import vsvm.data.model.AbstractDataModel;
import vsvm.gui.Environment;
import java.awt.Insets;
import java.io.File;
import java.io.IOException;

import libsvm.svm;
import libsvm.svm_model;
import javax.swing.JProgressBar;
import java.awt.FlowLayout;

public class TestClassifierForm extends JDialog {

	private static final long serialVersionUID = 100L;
	private JPanel jContentPane = null;
	private JPanel pnlButtons = null;
	private JPanel pnlCenter = null;
	private JPanel pnlLeft = null;
	private JPanel pnlRight = null;
	private JButton btnTest = null;
	private JButton btnCancel = null;
	private JPanel pnlTrainData = null;
	private JRadioButton rbtTrainingSet = null;
	private JRadioButton rbtDataModel = null;
	private JRadioButton rbtCross = null;
	private JLabel lblFolds = null;
	private JTextField txtFolds = null;
	private JRadioButton rbtSplit = null;
	private JLabel lblSplit = null;
	private JCheckBox chkRandom = null;
	private JLabel lblSampleCount = null;
	private JTextField txtSamples = null;
	private JComboBox cmbDataModel = null;
	private JComboBox cmbTestModel = null;
	private JTextField txtName = null;
	
	private ActionListener rbtListener;
	private ActionListener dmListener;
    private ActionListener tmListener;
	
	private AbstractClassifier classifier;
	
	private TestClassifierForm me = null;
	private JFileChooser fc = null;
	private svm_model model = null;
	private boolean threadBusy = false;
	
	
	public void doTest() {
		if (txtName.getText().trim().equals("")) {
			JOptionPane.showMessageDialog(this, "Name can not be empty.", "Error", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		TestingParameters tp = null;
		AbstractDataModel dm = (AbstractDataModel)cmbDataModel.getSelectedItem();
				
		if (rbtCross.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
				int folds = Integer.parseInt(txtFolds.getText());
				tp = new TestingParameters(dm, folds);
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(this, "Folds value must be a number.", "Error", JOptionPane.ERROR_MESSAGE);
				return;				
			}
		} else if (rbtTrainingSet.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			tp = new TestingParameters(dm);
		} else if (rbtDataModel.isSelected()) {
			AbstractDataModel tdm = (AbstractDataModel)cmbTestModel.getSelectedItem();
			if (tdm == null) {
				JOptionPane.showMessageDialog(this, "No test data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			if(radioTrain.isSelected()){
				if (dm == null) {
					JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(dm, tdm);
			} else if(radioModel.isSelected()){
				if(model == null){
					JOptionPane.showMessageDialog(this, "Trained data file must be chosen.", "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(model, tdm);
			}

		} else if (rbtSplit.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
				int split = Integer.parseInt(txtSamples.getText());
				if (split == 0 || split >= dm.getVectorCount()) {
					JOptionPane.showMessageDialog(this, "Split value must be between 1 and " + Integer.toString(dm.getVectorCount()-1), "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(dm, split, chkRandom.isSelected());
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(this, "Splits value must be a number.", "Error", JOptionPane.ERROR_MESSAGE);
				return;				
			}
		}
		
		if (tp != null) {
			AbstractTestSet ts = classifier.test(tp);
			ts.setName(txtName.getText());
			Environment.getEnvironment().getWorkspace().addTestSet(ts);
			ts.execute();
		}
		
		dispose();		
	}
	
	private TestingParameters tp = null;  //  @jve:decl-index=0:
	public void createParameters() {
		tp = null;
		AbstractDataModel dm = (AbstractDataModel)cmbDataModel.getSelectedItem();
		
		if (rbtCross.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
				int folds = Integer.parseInt(txtFolds.getText());
				tp = new TestingParameters(dm, folds);
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(this, "Folds value must be a number.", "Error", JOptionPane.ERROR_MESSAGE);
				return;				
			}
		} else if (rbtTrainingSet.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			tp = new TestingParameters(dm);
		} else if (rbtDataModel.isSelected()) {
			AbstractDataModel tdm = (AbstractDataModel)cmbTestModel.getSelectedItem();
			if (tdm == null) {
				JOptionPane.showMessageDialog(this, "No test data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			if(radioTrain.isSelected()){
				if (dm == null) {
					JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(dm, tdm);
			} else if(radioModel.isSelected()){
				if(model == null){
					JOptionPane.showMessageDialog(this, "Trained data file must be chosen.", "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(model, tdm);
			}
		} else if (rbtSplit.isSelected()) {
			if (dm == null) {
				JOptionPane.showMessageDialog(this, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
				int split = Integer.parseInt(txtSamples.getText());
				if (split == 0 || split >= dm.getVectorCount()) {
					JOptionPane.showMessageDialog(this, "Split value must be between 1 and " + Integer.toString(dm.getVectorCount()-1), "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				tp = new TestingParameters(dm, split, chkRandom.isSelected());
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(this, "Splits value must be a number.", "Error", JOptionPane.ERROR_MESSAGE);
				return;				
			}
		}
		dispose();
	}
	
//	public void loadCompatibleDataSources() {
//		ArrayList<AbstractDataModel> m = Environment.getEnvironment().getWorkspace().getDataModels();
//		AbstractDataModel mod = (AbstractDataModel)cmbDataModel.getSelectedItem();
//		
//		DefaultComboBoxModel cm = new DefaultComboBoxModel();
//		for (int i = 0; i < m.size(); ++i) {
//			if (m.get(i).compatible(mod))
//				cm.addElement(m.get(i));			
//		}
//		cmbDataModel.setModel(cm);
//		
//	}
	
	private void loadDataModels() {
		ArrayList<AbstractDataModel> m = Environment.getEnvironment().getWorkspace().getDataModels();
		cmbDataModel.setModel(new DefaultComboBoxModel(m.toArray()));
                cmbTestModel.setModel(new DefaultComboBoxModel(m.toArray()));
	}
	
	public void setDataModel(AbstractDataModel dm) {
		cmbDataModel.setSelectedItem(dm);
	}
	
	private class RadioListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			updateControls();
			if (e.getSource() == rbtDataModel) {
                                updateTestModels();
                                //loadCompatibleDataSources();
		}
		
                }
	}
	
	private class DataModelListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
                   // System.out.println("dataModelListener");
			updateDataModels();
		}
		
	}
	
	private void updateDataModels() {
		if (cmbDataModel.getSelectedItem() == null) return;
		
		//if (rbtDataModel.isSelected())
			//loadCompatibleDataSources();
		AbstractDataModel dm = (AbstractDataModel)cmbDataModel.getSelectedItem();
                //System.out.println(dm.toString());
		if (dm == null)
			lblSampleCount.setText("");
		else
			lblSampleCount.setText("/ " + Integer.toString(dm.getVectorCount()));		
	}
	
        private class TestModelListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
                    //System.out.println("testmodelListener");
			updateTestModels();
		}
		
	}
	
	private void updateTestModels() {
		if (cmbTestModel.getSelectedItem() == null) return;
		
		//if (rbtDataModel.isSelected())
		//	loadCompatibleDataSources();
		AbstractDataModel tm = (AbstractDataModel)cmbTestModel.getSelectedItem();
               // System.out.println(tm.toString());
		if (tm == null)
			lblSampleCount.setText("");
		else
			lblSampleCount.setText("/ " + Integer.toString(tm.getVectorCount()));		
	}
	
	/**
	 * This method initializes pnlButtons	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlButtons() {
		if (pnlButtons == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setHgap(25);
			pnlButtons = new JPanel();
			pnlButtons.setLayout(flowLayout);
			pnlButtons.setPreferredSize(new java.awt.Dimension(10,40));
			pnlButtons.add(getBtnTest(), null);
			pnlButtons.add(getBtnCancel(), null);
		}
		return pnlButtons;
	}

	/**
	 * This method initializes pnlCenter	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlCenter() {
		if (pnlCenter == null) {
			pnlCenter = new JPanel();
			pnlCenter.setLayout(new BorderLayout());
			pnlCenter.add(getPnlLeft(), BorderLayout.CENTER);
		}
		return pnlCenter;
	}

	/**
	 * This method initializes pnlLeft	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlLeft() {
		if (pnlLeft == null) {
			pnlLeft = new JPanel();
			pnlLeft.setLayout(new BorderLayout());
			pnlLeft.setPreferredSize(new java.awt.Dimension(260,260));
			pnlLeft.add(getPnlRight(), BorderLayout.CENTER);
			pnlLeft.add(getPnlTrainData(), BorderLayout.WEST);
		}
		return pnlLeft;
	}

	/**
	 * This method initializes pnlRight	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlRight() {
		if (pnlRight == null) {
			GridBagConstraints gridBagConstraints23 = new GridBagConstraints();
			gridBagConstraints23.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints23.gridx = 1;
			gridBagConstraints23.gridy = 9;
			gridBagConstraints23.gridwidth = 1;
			gridBagConstraints23.ipadx = 40;
			gridBagConstraints23.insets = new Insets(10, 10, 0, 5);
			GridBagConstraints gridBagConstraints141 = new GridBagConstraints();
			gridBagConstraints141.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints141.gridy = 7;
			gridBagConstraints141.weightx = 1.0;
			gridBagConstraints141.anchor = GridBagConstraints.WEST;
			gridBagConstraints141.insets = new Insets(0, 10, 0, 5);
			gridBagConstraints141.gridx = 1;
			GridBagConstraints gridBagConstraints131 = new GridBagConstraints();
			gridBagConstraints131.gridx = 0;
			gridBagConstraints131.insets = new Insets(0, 21, 0, 0);
			gridBagConstraints131.gridy = 2;
			GridBagConstraints gridBagConstraints111 = new GridBagConstraints();
			gridBagConstraints111.gridx = 1;
			gridBagConstraints111.gridy = 0;
			GridBagConstraints gridBagConstraints71 = new GridBagConstraints();
			gridBagConstraints71.gridx = 1;
			gridBagConstraints71.anchor = GridBagConstraints.SOUTHWEST;
			gridBagConstraints71.insets = new Insets(0, 10, 0, 0);
			gridBagConstraints71.weighty = 2.0;
			gridBagConstraints71.gridheight = 1;
			gridBagConstraints71.ipady = 0;
			gridBagConstraints71.gridy = 2;
			GridBagConstraints gridBagConstraints51 = new GridBagConstraints();
			gridBagConstraints51.gridx = 2;
			gridBagConstraints51.gridy = 0;
			GridBagConstraints gridBagConstraints41 = new GridBagConstraints();
			gridBagConstraints41.gridx = 0;
			gridBagConstraints41.gridy = 1;
			GridBagConstraints gridBagConstraints31 = new GridBagConstraints();
			gridBagConstraints31.gridx = 0;
			gridBagConstraints31.gridy = 0;
			TitledBorder titledBorder = javax.swing.BorderFactory.createTitledBorder(null, "Test properties", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null);
			titledBorder.setTitle("Evaluation settings");
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = 3;
			gridBagConstraints9.weighty = 1.0;
			gridBagConstraints9.gridy = 7;
			lblSampleCount = new JLabel();
			lblSampleCount.setText("");
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.gridx = 1;
			gridBagConstraints8.weighty = 1.0;
			gridBagConstraints8.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints8.insets = new Insets(0, 10, 0, 5);
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.gridy = 8;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.weighty = 1.0;
			gridBagConstraints6.insets = new java.awt.Insets(0,40,0,5);
			gridBagConstraints6.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints6.gridy = 7;
			lblSplit = new JLabel();
			lblSplit.setText("Test samples");
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 0;
			gridBagConstraints5.insets = new java.awt.Insets(0,10,0,0);
			gridBagConstraints5.gridwidth = 2;
			gridBagConstraints5.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints5.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints5.weighty = 1.0;
			gridBagConstraints5.gridy = 6;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints4.gridy = 5;
			gridBagConstraints4.weightx = 1.0;
			gridBagConstraints4.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints4.insets = new Insets(0, 10, 0, 5);
			gridBagConstraints4.weighty = 1.0;
			gridBagConstraints4.gridx = 1;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 0;
			gridBagConstraints3.anchor = java.awt.GridBagConstraints.EAST;
			gridBagConstraints3.insets = new java.awt.Insets(0,0,0,5);
			gridBagConstraints3.weighty = 1.0;
			gridBagConstraints3.gridy = 5;
			lblFolds = new JLabel();
			lblFolds.setText("Folds");
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints2.insets = new java.awt.Insets(0,10,0,0);
			gridBagConstraints2.gridwidth = 2;
			gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.weighty = 1.0;
			gridBagConstraints2.gridy = 4;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints1.insets = new java.awt.Insets(0,10,0,0);
			gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.gridwidth = 2;
			gridBagConstraints1.weightx = 1.0;
			gridBagConstraints1.weighty = 1.0;
			gridBagConstraints1.gridy = 1;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints.gridwidth = 2;
			gridBagConstraints.insets = new java.awt.Insets(0,10,0,0);
			gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.weighty = 1.0;
			gridBagConstraints.gridy = 0;
			pnlRight = new JPanel();
			pnlRight.setLayout(new GridBagLayout());
			pnlRight.setBorder(titledBorder);
			pnlRight.add(getRbtTrainingSet(), gridBagConstraints);
			pnlRight.add(getRbtDataModel(), gridBagConstraints1);
			pnlRight.add(getRbtCross(), gridBagConstraints2);
			pnlRight.add(lblFolds, gridBagConstraints3);
			pnlRight.add(getTxtFolds(), gridBagConstraints4);
			pnlRight.add(getRbtSplit(), gridBagConstraints5);
			pnlRight.add(lblSplit, gridBagConstraints6);
			pnlRight.add(getChkRandom(), gridBagConstraints8);
			pnlRight.add(lblSampleCount, gridBagConstraints9);
			pnlRight.add(getBtnOpen(), gridBagConstraints71);
			pnlRight.add(getJPanel(), gridBagConstraints131);
			pnlRight.add(getTxtSamples(), gridBagConstraints141);
			pnlRight.add(getJProgressBar(), gridBagConstraints23);
			
			ButtonGroup gr = new ButtonGroup();
			gr.add(getRbtCross());
			gr.add(getRbtDataModel());
			gr.add(getRbtSplit());
			gr.add(getRbtTrainingSet());
		}
		return pnlRight;
	}

	/**
	 * This method initializes btnTest	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtnTest() {
		if (btnTest == null) {
			btnTest = new JButton();
			btnTest.setPreferredSize(new java.awt.Dimension(80,25));
			btnTest.setText("Test");
			btnTest.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) 
				{
					if(threadBusy)
					{
						JOptionPane.showMessageDialog(me, "Testing! " +
								"Press Cancel to stop.", "Thread is busy!", 0);
						return;
					}
					threadTest = new ThreadTest();
					threadTest.start();
				}
			});
		}
		return btnTest;
	}

	/**
	 * This method initializes btnCancel	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtnCancel() {
		if (btnCancel == null) {
			btnCancel = new JButton();
			btnCancel.setText("Cancel");
			btnCancel.addActionListener(new java.awt.event.ActionListener() {
				@SuppressWarnings("deprecation")
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(threadBusy && threadTest != null)
					{
						threadTest.stop();
					}
					dispose();
				}
			});
			btnCancel.setPreferredSize(new java.awt.Dimension(80,25));
		}
		return btnCancel;
	}

	/**
	 * This method initializes pnlTrainData	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlTrainData() {
		if (pnlTrainData == null) {
			GridBagConstraints gridBagConstraints20 = new GridBagConstraints();
			gridBagConstraints20.gridx = 0;
			gridBagConstraints20.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints20.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints20.gridy = 0;
			jLabel5 = new JLabel();
			jLabel5.setText("Name");
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 0;
			gridBagConstraints7.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints7.gridy = 1;
			jLabel4 = new JLabel();
			jLabel4.setText("Train data");
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.fill = GridBagConstraints.BOTH;
			gridBagConstraints12.gridx = 1;
			gridBagConstraints12.gridy = 1;
			gridBagConstraints12.weightx = 1.0;
			gridBagConstraints12.insets = new Insets(5, 5, 5, 5);
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints13.gridy = 1;
			gridBagConstraints13.gridx = 0;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints10.gridx = 0;
			gridBagConstraints10.gridy = 0;
			gridBagConstraints10.insets = new Insets(5, 5, 5, 5);
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.fill = GridBagConstraints.BOTH;
			gridBagConstraints11.gridx = 1;
			gridBagConstraints11.gridy = 0;
			gridBagConstraints11.weightx = 1.0;
			gridBagConstraints11.insets = new Insets(5, 5, 5, 5);
			GridBagConstraints gridBagConstraints18 = new GridBagConstraints();
			gridBagConstraints18.gridx = 0;
			gridBagConstraints18.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints18.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints18.gridy = 3;
			jLabel2 = new JLabel();
			jLabel2.setText("Test data");
			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
			gridBagConstraints15.fill = GridBagConstraints.BOTH;
			gridBagConstraints15.gridx = 1;
			gridBagConstraints15.gridy = 3;
			gridBagConstraints15.weightx = 1.0;
			gridBagConstraints15.insets = new Insets(5, 5, 5, 5);
			pnlTrainData = new JPanel();
			pnlTrainData.setLayout(new GridBagLayout());
			pnlTrainData.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Testing", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			pnlTrainData.add(getCmbTestModel(), gridBagConstraints15);
			pnlTrainData.add(jLabel2, gridBagConstraints18);
			pnlTrainData.add(getTxtName(), gridBagConstraints11);
			pnlTrainData.add(getCmbDataModel(), gridBagConstraints12);
			pnlTrainData.add(jLabel4, gridBagConstraints7);
			pnlTrainData.add(jLabel5, gridBagConstraints20);
		}
		return pnlTrainData;
	}

	/**
	 * This method initializes pnlTestData	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	/*private JPanel getPnlTestData() {
		if (pnlTestData == null) {
			lblName = new JLabel();
			lblName.setText("Result file name");
			jLabel = new JLabel();
			jLabel.setText("Data model");
		}
		return pnlTestData;
	}
*/
	/**
	 * This method initializes rbtTrainingSet	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRbtTrainingSet() {
		if (rbtTrainingSet == null) {
			rbtTrainingSet = new JRadioButton();
			rbtTrainingSet.setText("Use training set");
			rbtTrainingSet.addActionListener(rbtListener);
		}
		return rbtTrainingSet;
	}

	/**
	 * This method initializes rbtDataModel	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRbtDataModel() {
		if (rbtDataModel == null) {
			rbtDataModel = new JRadioButton();
			rbtDataModel.setText("Use separate data");
			rbtDataModel.setSelected(true);
			rbtDataModel.addActionListener(rbtListener);
		}
		return rbtDataModel;
	}

	/**
	 * This method initializes rbtCross	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRbtCross() {
		if (rbtCross == null) {
			rbtCross = new JRadioButton();
			rbtCross.setText("Use cross-validation");
			//rbtCross.setSelected(true);
			rbtCross.addActionListener(rbtListener);
		}
		return rbtCross;
	}

	/**
	 * This method initializes txtFolds	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getTxtFolds() {
		if (txtFolds == null) {
			txtFolds = new JTextField();
			txtFolds.setText("10");
		}
		return txtFolds;
	}

	/**
	 * This method initializes rbtSplit	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRbtSplit() {
		if (rbtSplit == null) {
			rbtSplit = new JRadioButton();
			rbtSplit.setText("Use part of data");
			rbtSplit.addActionListener(rbtListener);
		}
		return rbtSplit;
	}

	/**
	 * This method initializes chkRandom	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getChkRandom() {
		if (chkRandom == null) {
			chkRandom = new JCheckBox();
			chkRandom.setText("Random");
		}
		return chkRandom;
	}

	/**
	 * This method initializes txtSamples	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getTxtSamples() {
		if (txtSamples == null) {
			txtSamples = new JTextField();
			txtSamples.setPreferredSize(new java.awt.Dimension(60,20));
		}
		return txtSamples;
	}

	/**
	 * This method initializes cmbDataModel	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getCmbDataModel() {
		if (cmbDataModel == null) {
			cmbDataModel = new JComboBox();
			cmbDataModel.setPreferredSize(new java.awt.Dimension(220,25));
			cmbDataModel.addActionListener(dmListener);
		}
		return cmbDataModel;
	}

	/**
	 * This method initializes cmbTestModel	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getCmbTestModel() {
		if (cmbTestModel == null) {
			cmbTestModel = new JComboBox();
			cmbTestModel.setPreferredSize(new java.awt.Dimension(220,25));
                        cmbTestModel.addActionListener(tmListener);
		}
		return cmbTestModel;
	}

	/**
	 * This method initializes txtName	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getTxtName() {
		if (txtName == null) {
			txtName = new JTextField();
			txtName.setPreferredSize(new java.awt.Dimension(180,20));
		}
		return txtName;
	}

	/**
	 * This method initializes btnOpen	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtnOpen() {
		if (btnOpen == null) {
			btnOpen = new JButton();
			btnOpen.setText("...");
			btnOpen.setEnabled(false);
			btnOpen.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					 int returnVal = fc.showOpenDialog(me);
					 	model = null;
				        if (returnVal == JFileChooser.APPROVE_OPTION) {
				            File file = fc.getSelectedFile();
				            try {
								model = svm.svm_load_model(file.getPath());
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								//e1.printStackTrace();
								JOptionPane.showMessageDialog(me, "Model loading failed.", "Error", JOptionPane.ERROR_MESSAGE);
							}				            
				            
				        } 
				}
			});
		}
		return btnOpen;
	}

	
	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints19 = new GridBagConstraints();
			gridBagConstraints19.gridx = 1;
			gridBagConstraints19.insets = new Insets(0, 10, 0, 0);
			gridBagConstraints19.gridy = 1;
			jLabel3 = new JLabel();
			jLabel3.setText("Trained data model");
			GridBagConstraints gridBagConstraints17 = new GridBagConstraints();
			gridBagConstraints17.gridx = 1;
			gridBagConstraints17.anchor = GridBagConstraints.WEST;
			gridBagConstraints17.insets = new Insets(0, 10, 0, 0);
			gridBagConstraints17.gridy = 0;
			jLabel1 = new JLabel();
			jLabel1.setText("Train data");
			GridBagConstraints gridBagConstraints16 = new GridBagConstraints();
			gridBagConstraints16.gridx = 0;
			gridBagConstraints16.gridy = 1;
			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
			gridBagConstraints14.gridx = 0;
			gridBagConstraints14.gridy = 0;
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			jPanel.add(getRadioTrain(), gridBagConstraints14);
			jPanel.add(getRadioModel(), gridBagConstraints16);
			jPanel.add(jLabel1, gridBagConstraints17);
			jPanel.add(jLabel3, gridBagConstraints19);
		}
		return jPanel;
	}

	/**
	 * This method initializes radioTrain	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRadioTrain() {
		if (radioTrain == null) {
			radioTrain = new JRadioButton();
			radioTrain.setSelected(true);
			radioTrain.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					radioModel.setSelected(false);
					cmbDataModel.setEnabled(true);
					btnOpen.setEnabled(false);
					radioTrain.setSelected(true);
				}
			});
		}
		return radioTrain;
	}

	/**
	 * This method initializes radioModel	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getRadioModel() {
		if (radioModel == null) {
			radioModel = new JRadioButton();

			radioModel.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					cmbDataModel.setEnabled(false);
					radioTrain.setSelected(false);
					radioModel.setSelected(true);
					btnOpen.setEnabled(true);
				}
			});
		}
		return radioModel;
	}

	/**
	 * This method initializes jProgressBar	
	 * 	
	 * @return javax.swing.JProgressBar	
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
		}
		return jProgressBar;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TestClassifierForm t = new TestClassifierForm(null, null);
		t.setVisible(true);

	}

	/**
	 * This is the default constructor
	 */
	public TestClassifierForm(Component parent, AbstractClassifier cls) {
		super();
		me = this;
		fc = new JFileChooser(".");
		dmListener = new DataModelListener();
        tmListener = new TestModelListener();
		rbtListener = new RadioListener();
		initialize();
		
		setLocationRelativeTo(parent);
		classifier = cls;
		
		loadDataModels();
		
		txtName.setText("results_");
		updateDataModels();
	}
	
	private boolean noTest = false;
	private JLabel jLabel2 = null;
	private JButton btnOpen = null;
	private JPanel jPanel = null;
	private JRadioButton radioTrain = null;
	private JRadioButton radioModel = null;
	private JLabel jLabel1 = null;
	private JLabel jLabel3 = null;
	private JLabel jLabel4 = null;
	private JLabel jLabel5 = null;
	public void setNoTest() {
		noTest = true;
		//pnlTestData.setEnabled(false);
		txtName.setEnabled(false);
		txtName.setText("");
		//lblName.setEnabled(false);		
	}
	
	public TestingParameters getParameters() {
		return tp;		
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(653, 369);
		this.setResizable(false);
		this.setModal(true);
		this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		this.setTitle("Test properties");
		this.setContentPane(getJContentPane());
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@SuppressWarnings("deprecation")
			public void windowClosing(java.awt.event.WindowEvent e) {
				if(threadBusy && threadTest != null){
					threadTest.stop();
				}
			}
		});
		updateControls();
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getPnlButtons(), java.awt.BorderLayout.SOUTH);
			jContentPane.add(getPnlCenter(), java.awt.BorderLayout.CENTER);
		}
		return jContentPane;
	}
	
	
	private void updateControls() {
		if (rbtCross.isSelected()) {
			txtFolds.setEnabled(true);
			txtSamples.setEnabled(false);
			chkRandom.setEnabled(false);
			cmbTestModel.setEnabled(false);
			btnOpen.setEnabled(false);
			radioTrain.setEnabled(false);
			radioModel.setEnabled(false);
			
		} else if (rbtTrainingSet.isSelected()) {
			txtFolds.setEnabled(false);
			txtSamples.setEnabled(false);
			chkRandom.setEnabled(false);
			cmbTestModel.setEnabled(false);
			btnOpen.setEnabled(false);
			radioTrain.setEnabled(false);
			radioModel.setEnabled(false);
			
		} else if (rbtDataModel.isSelected()) {
			txtFolds.setEnabled(false);
			txtSamples.setEnabled(false);
			chkRandom.setEnabled(false);
			cmbTestModel.setEnabled(true);
			radioTrain.setEnabled(true);
			radioModel.setEnabled(true);
			
		} else if (rbtSplit.isSelected()) {
			txtFolds.setEnabled(false);
			txtSamples.setEnabled(true);
			chkRandom.setEnabled(true);
			cmbTestModel.setEnabled(false);
			btnOpen.setEnabled(false);
			radioTrain.setEnabled(false);
			radioModel.setEnabled(false);
		}
	}
	
	private Thread threadTest = null;
	private JProgressBar jProgressBar = null;
	private class ThreadTest extends Thread {

	    public void run() {
	    	try
	    	{
		    	threadBusy = true;
		    	jProgressBar.setIndeterminate(true);
		    	if (noTest)
					createParameters();
				else
					doTest();
		    	jProgressBar.setIndeterminate(false);
		    	threadBusy = false;
			} catch (OutOfMemoryError e) 
			{
				jProgressBar.setIndeterminate(false);
				threadBusy = false;
				JOptionPane.showMessageDialog(me, "There is not enough memory for " +
						"the desired calculations!", "Out of Memory", JOptionPane.ERROR_MESSAGE);
			}
	    }

	}

}  //  @jve:decl-index=0:visual-constraint="10,-17"

